// ============================================
// 02 - 数据类型 (Data Types)
// ============================================

/// Rust 是静态类型语言，编译时必须知道所有变量的类型
/// Rust 的数据类型分为两类：标量类型和复合类型

// ==================== 标量类型 ====================

/// 整数类型 (Integer Types)
/// 有符号: i8, i16, i32, i64, i128, isize
/// 无符号: u8, u16, u32, u64, u128, usize
pub fn integer_types() {
    println!("\n=== 整数类型 ===");
    
    // 不同大小的有符号整数
    let a: i8 = -128;       // -128 到 127
    let b: i16 = 32_000;    // -32,768 到 32,767
    let c: i32 = 2_147_483_647; // -2^31 到 2^31-1 (默认类型)
    let d: i64 = 9_223_372_036_854_775_807; // -2^63 到 2^63-1
    
    println!("i8: {}, i16: {}, i32: {}, i64: {}", a, b, c, d);
    
    // 无符号整数
    let e: u8 = 255;        // 0 到 255
    let f: u32 = 4_294_967_295; // 0 到 2^32-1
    
    println!("u8: {}, u32: {}", e, f);
    
    // isize 和 usize 取决于程序运行的计算机架构
    let g: isize = 100;
    let h: usize = 200;
    println!("isize: {}, usize: {}", g, h);
    
    // 整数字面量的不同表示方式
    let decimal = 98_222;           // 十进制
    let hex = 0xff;                 // 十六进制
    let octal = 0o77;               // 八进制
    let binary = 0b1111_0000;       // 二进制
    let byte = b'A';                // 字节 (仅限 u8)
    
    println!("十进制: {}, 十六进制: {}, 八进制: {}, 二进制: {}, 字节: {}", 
             decimal, hex, octal, binary, byte);
}

/// 浮点类型 (Floating-Point Types)
/// f32: 单精度浮点数
/// f64: 双精度浮点数 (默认类型)
pub fn floating_point_types() {
    println!("\n=== 浮点类型 ===");
    
    let x = 2.0;        // f64 (默认)
    let y: f32 = 3.0;   // f32
    
    println!("f64: {}, f32: {}", x, y);
    
    // 浮点数运算
    let sum = 5.5 + 10.2;
    let difference = 95.5 - 4.3;
    let product = 4.0 * 30.0;
    let quotient = 56.7 / 32.2;
    
    println!("加: {}, 减: {}, 乘: {}, 除: {}", sum, difference, product, quotient);
}

/// 数值运算
pub fn numeric_operations() {
    println!("\n=== 数值运算 ===");
    
    // 基本算术运算
    let sum = 5 + 10;
    let difference = 95 - 4;
    let product = 4 * 30;
    let quotient = 56 / 32;      // 整数除法，结果为 1
    let remainder = 43 % 5;       // 取模运算
    
    println!("加法: {}", sum);
    println!("减法: {}", difference);
    println!("乘法: {}", product);
    println!("除法: {}", quotient);
    println!("取模: {}", remainder);
    
    // 使用方法进行数学运算
    let abs_value = (-42i32).abs();
    let power = 2i32.pow(8);
    let sqrt = (16.0f64).sqrt();
    
    println!("绝对值: {}, 幂运算: {}, 平方根: {}", abs_value, power, sqrt);
}

/// 布尔类型 (Boolean Type)
/// 只有两个值: true 和 false
pub fn boolean_type() {
    println!("\n=== 布尔类型 ===");
    
    let t = true;
    let f: bool = false;
    
    println!("true: {}, false: {}", t, f);
    
    // 布尔运算
    let and = true && false;
    let or = true || false;
    let not = !true;
    
    println!("与运算: {}, 或运算: {}, 非运算: {}", and, or, not);
    
    // 比较运算返回布尔值
    let greater = 5 > 3;
    let equal = 5 == 5;
    let not_equal = 5 != 3;
    
    println!("大于: {}, 等于: {}, 不等于: {}", greater, equal, not_equal);
}

/// 字符类型 (Character Type)
/// char 类型代表一个 Unicode 标量值
pub fn character_type() {
    println!("\n=== 字符类型 ===");
    
    let c = 'z';
    let z = 'ℤ';
    let heart_eyed_cat = '😻';
    let chinese = '中';
    
    println!("普通字符: {}", c);
    println!("特殊符号: {}", z);
    println!("表情符号: {}", heart_eyed_cat);
    println!("中文字符: {}", chinese);
    
    // 注意: char 使用单引号，字符串使用双引号
    // let invalid = "a"; // 这是字符串，不是字符
}

// ==================== 复合类型 ====================

/// 元组类型 (Tuple Type)
/// 元组可以将多个不同类型的值组合成一个复合类型
pub fn tuple_type() {
    println!("\n=== 元组类型 ===");
    
    // 创建元组
    let tup: (i32, f64, u8) = (500, 6.4, 1);
    println!("元组: {:?}", tup);
    
    // 解构元组
    let (x, y, z) = tup;
    println!("解构后: x={}, y={}, z={}", x, y, z);
    
    // 使用索引访问元组元素
    let first = tup.0;
    let second = tup.1;
    let third = tup.2;
    println!("通过索引访问: {}, {}, {}", first, second, third);
    
    // 空元组 - 单元类型 (unit type)
    let unit = ();
    println!("单元类型: {:?}", unit);
}

/// 数组类型 (Array Type)
/// 数组中的每个元素类型必须相同，且长度固定
pub fn array_type() {
    println!("\n=== 数组类型 ===");
    
    // 创建数组
    let a = [1, 2, 3, 4, 5];
    println!("数组: {:?}", a);
    
    // 指定类型和长度
    let b: [i32; 5] = [1, 2, 3, 4, 5];
    println!("指定类型的数组: {:?}", b);
    
    // 创建包含相同值的数组
    let c = [3; 5]; // 等同于 [3, 3, 3, 3, 3]
    println!("相同值的数组: {:?}", c);
    
    // 访问数组元素
    let first = a[0];
    let second = a[1];
    println!("第一个元素: {}, 第二个元素: {}", first, second);
    
    // 数组长度
    let length = a.len();
    println!("数组长度: {}", length);
    
    // 遍历数组
    print!("遍历数组: ");
    for element in &a {
        print!("{} ", element);
    }
    println!();
    
    // 注意: 数组越界访问会导致运行时 panic
    // let invalid = a[10]; // ❌ 运行时错误: index out of bounds
}

/// 字符串类型基础
/// Rust 有两种主要的字符串类型: &str (字符串切片) 和 String
pub fn string_basics() {
    println!("\n=== 字符串类型 ===");
    
    // 字符串字面量 - &str 类型 (不可变)
    let s1: &str = "Hello, world!";
    println!("字符串字面量: {}", s1);
    
    // String 类型 - 可变、可增长的字符串
    let s2 = String::from("Hello, Rust!");
    println!("String 类型: {}", s2);
    
    let mut s3 = String::from("Hello");
    s3.push_str(", world!");
    println!("可变 String: {}", s3);
    
    // 字符串包含 UTF-8 编码
    let hello_chinese = "你好，世界！";
    let hello_japanese = "こんにちは";
    let hello_korean = "안녕하세요";
    
    println!("中文: {}", hello_chinese);
    println!("日文: {}", hello_japanese);
    println!("韩文: {}", hello_korean);
}

/// 类型转换
pub fn type_conversion() {
    println!("\n=== 类型转换 ===");
    
    // 使用 as 进行显式类型转换
    let a = 3.14f64;
    let b = a as i32;
    println!("f64 转 i32: {} -> {}", a, b);
    
    let c = 255u8;
    let d = c as i32;
    println!("u8 转 i32: {} -> {}", c, d);
    
    // 使用 parse 将字符串转换为数字
    let num_str = "42";
    let num: i32 = num_str.parse().expect("不是有效的数字");
    println!("字符串转数字: '{}' -> {}", num_str, num);
    
    // 使用 to_string 将数字转换为字符串
    let num2 = 123;
    let str2 = num2.to_string();
    println!("数字转字符串: {} -> '{}'", num2, str2);
}

/// 类型别名
pub fn type_aliases() {
    println!("\n=== 类型别名 ===");
    
    // 使用 type 关键字创建类型别名
    type Kilometers = i32;
    
    let distance: Kilometers = 100;
    println!("距离: {} 公里", distance);
    
    // 类型别名常用于简化复杂类型
    type Point = (i32, i32);
    let origin: Point = (0, 0);
    println!("原点坐标: {:?}", origin);
}

/// 主函数 - 演示所有功能
#[allow(dead_code)]
pub fn main() {
    println!("╔════════════════════════════════════════╗");
    println!("║   Rust 数据类型教程                    ║");
    println!("╚════════════════════════════════════════╝");
    
    integer_types();
    floating_point_types();
    numeric_operations();
    boolean_type();
    character_type();
    tuple_type();
    array_type();
    string_basics();
    type_conversion();
    type_aliases();
    
    println!("\n✅ 数据类型教程完成！");
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_integer_types() {
        let x: i32 = 42;
        assert_eq!(x, 42);
    }
    
    #[test]
    fn test_tuple() {
        let tup = (1, 2.5, 'a');
        assert_eq!(tup.0, 1);
        assert_eq!(tup.1, 2.5);
        assert_eq!(tup.2, 'a');
    }
    
    #[test]
    fn test_array() {
        let arr = [1, 2, 3, 4, 5];
        assert_eq!(arr.len(), 5);
        assert_eq!(arr[0], 1);
    }
}

